#!/usr/bin/env python3
"""
二维码服务 - 生成和验证访客二维码
"""

import json
from datetime import datetime, timedelta
from typing import Any

from app.core.config import settings
from app.services.crypto_service import crypto_service


class QRCodeService:
    """二维码服务类"""

    async def generate_visitor_qrcode(self, visitor_data: dict[str, Any]) -> str:
        """
        生成访客二维码数据

        Args:
            visitor_data: 访客数据，包含以下字段：
                - visitor_id: 访客ID
                - name: 姓名
                - id_card: 身份证号
                - company: 单位
                - visit_reason: 访问事由
                - interviewee: 被访人
                - is_special: 是否特殊访客

        Returns:
            str: 加密后的二维码数据字符串
        """
        try:
            # 构建二维码数据
            qr_data = {
                "version": "1.0",
                "type": "visitor",
                "visitor_id": visitor_data["visitor_id"],
                "name": visitor_data["name"],
                "id_card": visitor_data["id_card"],
                "company": visitor_data.get("company", ""),
                "visit_reason": visitor_data["visit_reason"],
                "interviewee": visitor_data["interviewee"],
                "is_special": visitor_data.get("is_special", False),
                "timestamp": datetime.now().isoformat(),
                "expire_time": (datetime.now() + timedelta(minutes=settings.QRCODE_EXPIRE_MINUTES)).isoformat(),
            }

            # 加密数据
            encrypted_data = crypto_service.encrypt_data(qr_data)

            # 创建签名负载
            signature_payload = {"data": encrypted_data, "timestamp": datetime.now().isoformat()}

            # 生成JWT签名
            jwt_token = crypto_service.create_jwt_token(signature_payload)

            # 组合最终二维码数据
            final_qr_data = {"encrypted_data": encrypted_data, "signature": jwt_token}

            return json.dumps(final_qr_data, ensure_ascii=False)

        except Exception as e:
            raise ValueError(f"二维码生成失败: {str(e)}")

    async def verify_qrcode(self, qr_code_data: str) -> dict[str, Any]:
        """
        验证二维码数据

        Args:
            qr_code_data: 二维码数据字符串

        Returns:
            dict[str, Any]: 验证后的访客数据
        """
        try:
            # 解析JSON数据
            qr_data = json.loads(qr_code_data)

            # 验证签名
            signature_payload = crypto_service.verify_jwt_token(qr_data["signature"])

            # 验证数据一致性
            if qr_data["encrypted_data"] != signature_payload["data"]:
                raise ValueError("数据签名不匹配")

            # 解密数据
            visitor_data = crypto_service.decrypt_data(qr_data["encrypted_data"])

            # 验证过期时间
            expire_time = datetime.fromisoformat(visitor_data["expire_time"])
            if datetime.now() > expire_time:
                raise ValueError("二维码已过期")

            return visitor_data

        except json.JSONDecodeError:
            raise ValueError("无效的二维码格式")
        except KeyError as e:
            raise ValueError(f"二维码数据缺少必要字段: {str(e)}")
        except Exception as e:
            raise ValueError(f"二维码验证失败: {str(e)}")

    async def validate_visitor_access(self, visitor_data: dict[str, Any]) -> dict[str, Any]:
        """
        验证访客访问权限

        Args:
            visitor_data: 解密后的访客数据
        
        Returns:
            dict[str, Any]: 访问验证结果
        """
        try:
            # 检查访客状态
            visitor_id = visitor_data["visitor_id"]

            # 这里可以添加更多的访问验证逻辑
            # 例如检查访客状态、访问时间等

            result = {
                "valid": True,
                "visitor_id": visitor_id,
                "name": visitor_data["name"],
                "message": "访问验证通过",
                "timestamp": datetime.now().isoformat(),
            }

            # 如果是特殊访客，添加额外信息
            if visitor_data.get("is_special", False):
                result["is_special"] = True
                result["special_notes"] = "特殊访客，请特别注意"

            return result

        except Exception as e:
            return {"valid": False, "error": f"访问验证失败: {str(e)}", "timestamp": datetime.now().isoformat()}


# 全局二维码服务实例
qrcode_service = QRCodeService()
